Built with R version 4.4.0.
Exploring visit
data
Summary of
visits
Remember that in the data wrangling stage, we created a new sample
identifier based on site and date which we called VisitID. Let’s take a
look at the variables associated with each VisitID:
glimpse(visits)
## Rows: 1,867
## Columns: 7
## $ VisitID <chr> "1_2001-07-24", "1_2002-03-25", "1_2001-04-26", "1_2002-07-…
## $ Replicates <int> 5, 7, 4, 4, 5, 3, 4, 2, 6, 1, 2, 2, 6, 4, 4, 4, 4, 3, 2, 2,…
## $ Date <date> 2001-07-24, 2002-03-25, 2001-04-26, 2002-07-24, 2003-03-22…
## $ Lat <dbl> 58.56626, 58.56296, 58.56408, 58.56755, 58.55804, 58.56858,…
## $ Lon <dbl> -134.9105, -134.9082, -134.9137, -134.9133, -134.9102, -134…
## $ MeshSize <dbl> 3.2, 3.2, 3.2, 3.2, 3.2, 3.2, 3.2, 3.2, 3.2, 3.2, 3.2, 3.2,…
## $ Cluster <fct> 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 326,…
During the wrangling stage, I decided that Replicates and MeshSize
should be the main covariates that needed consideration. At this point
they are classed as integers/numbers, but we will probably want them to
be factors instead. Cluster is a byproduct of clustering some sites
together, so it may not be needed if we’re using Lat/Lon as our primary
explanatory variable. Still, it could be a useful grouping factor later
on. Date will likely be mutated into multiple additional periods (day of
year, month, year) to see if any of those factors are useful in
explaining fish data. We’ll address edits to these variables as they
come up in our exploration.
Spatial
distribution
leaflet(visits) %>%
addTiles(options = tileOptions(minZoom = 3.5,
zIndex = 0.5)) %>%
setView(lat = 65, lng = -152, zoom = 3.5) %>%
addSimpleGraticule(interval = 5) %>%
addCircleMarkers(lng = ~Lon, lat = ~Lat,
stroke = FALSE,
popup = ~VisitID,
clusterOptions = markerClusterOptions())
In the map above we can view all of our samples from across Alaska.
Leaflet options are nice because you can optionally group samples on the
map and show a boundary polygon of the area they cover when you hover
over their icon. At the minimum zoom level (3.5), we see the largest
group spanning nearly all of Southeast Alaska, followed by a group in
Southcentral that covers Prince William Sound, Cook Inlet, and the
northern half of Kodiak Island. The third largest group forms a much
smaller polygon area around Utqiagvik. From there, we see even smaller
groups from the Eastern Beaufort Sea around Kaktovik, the Bering Strait
and Southern Chukchi Sea near Kotzebue, and Bristol Bay. There are also
two groups from the Alaska Peninsula and Aleutian Islands, one focused
around Adak and another spanning from Sand Point to Unalaska. We can see
how subsets of the samples change by zooming in. When there are single
samples in view, hovering over those will tell us its VisitID name.
Obviously, this visualization of the data is not perfect and pretty
rough- note that the groups are formed by the overlap of samples based
on pixel radius (10). For example, the polygon of samples from Bristol
Bay at the minimum zoom level actually crosses the Alaska Peninsula to
include a sample from Aghiyuk Island. Although, the map is useful in
gaining a general understanding of the existing clusters of samples
within the NFA database.
Regions
We may want to define a spatial factor based on these rough groupings
as a starting place to see if the smaller, more isolated groups should
be lumped with other groups or not. Actually, the NFA already has a
Region classifier per site, but the reason I do not want to use it is
because they linked Region to SiteID. When we created our new VisitID,
some samples now contained two Region labels- these were mostly cases
from around Utqiagvik where some were labelled as Chuckchi and others as
Beaufort but actually occurred on the same day and within a very short
distance of each other.
Instead of using the the given regional classes, let’s just make our
own variable called ‘Region’ and add it to the our visits df:
# Start with events so that we can make use of Location info for unique cases,
regions = events %>%
select(EventID, VisitID, Lat, Lon, Location) %>%
mutate(Region = case_when(Lat > 69 & Lat < 80 & Lon > -150 & Lon < -140 ~ "Beaufort East",
Lat > 69 & Lat < 80 & Lon > -160 & Lon < -150 ~ "Chukchi/Beaufort",
Lat > 65 & Lat < 69 & Lon > -170 & Lon < -160 ~ "Chukchi South",
Lat > 57 & Lat < 60 & Lon > -165 & Lon < -155 ~ "Bristol Bay",
Lat > 50 & Lat < 55 & Lon > -180 & Lon < -175 ~ "Aleutians Adak",
Lat > 50 & Lat < 55 & Lon > -170 & Lon < -165 ~ "Aleutians Unalaska",
Lat > 55 & Lat < 65 & Lon > -155 & Lon < -145 ~ "GOA Southcentral",
Lat > 53 & Lat < 61 & Lon > -148 & Lon < -130 ~ "GOA Southeast"))
# Check which samples we missed,
filter(regions, is.na(Region))
## # A tibble: 7 × 6
## EventID VisitID Lat Lon Location Region
## <dbl> <chr> <dbl> <dbl> <chr> <chr>
## 1 6635 1564_2006-06-22 52.7 -171. Yunaska Island <NA>
## 2 6636 1565_2006-07-26 56.2 -157. Semidi Islands, Aghiyuk Island <NA>
## 3 6637 1566_2006-07-31 55.1 -160. Shumagin Islands, Bendel Island <NA>
## 4 6638 1566_2006-07-31 55.1 -160. Shumagin Islands, Bendel Island <NA>
## 5 6639 1568_2006-07-31 55.1 -160. Shumagin Islands, Spectacle Island <NA>
## 6 6640 1569_2006-07-31 55.1 -160. Shumagin Islands, Nagai Island, Mi… <NA>
## 7 6641 1569_2006-07-31 55.1 -160. Shumagin Islands, Nagai Island, Mi… <NA>
# Let's address those using Location,
regions = mutate(regions,
Region = case_when(!is.na(Region) ~ Region,
is.na(Region) & str_detect(Location, "Yunaska") ~ "Aleutians Yunaska",
is.na(Region) & str_detect(Location, "Aghiyuk") ~ "Aleutians Aghiyuk",
is.na(Region) & str_detect(Location, "Shumagin") ~ "Aleutians Shumagin"))
# Check again (should be 0),
filter(regions, is.na(Region)) %>% nrow()
## [1] 0
Now let’s add Region as a factor to our visits df, and show it on a
map. Since we’re manipulating our data objects again, let’s also rename
visits so that we can keep track of our changes.
# Call our wrangled df version visits.0 and remove the non-version 'visits' if it's there,
if ("visits" %in% ls()) assign("visits.0", visits)
if ("visits" %in% ls()) rm(visits)
# Make Region a factor and join by VisitID,
visits.1 = regions %>%
select(VisitID, Region) %>%
distinct() %>%
mutate(Region = as.factor(Region)) %>%
left_join(visits.0, ., by = "VisitID")
# Function for regional palette
palette.region = colorFactor(palette = brewer.pal(n = visits.1$Region %>% n_distinct(),
name = 'Spectral'),
domain = factor(visits.1$Region))
# Map
leaflet(visits.1) %>%
addTiles() %>%
addCircleMarkers(lng = ~Lon, lat = ~Lat,
color = ~palette.region(Region),
fillColor = ~palette.region(Region),
popup = ~paste(Region, VisitID),
stroke = FALSE) %>%
addLegend(position = "topright",
pal = palette.region, values = ~Region,
title = "Region",
opacity = 0.75)

Like we saw before, the majority of our samples are located in the
Gulf of Alaska (GOA), namely Southeast (SEAk) and Southcentral (SCAK).
If we were to look at differences in catach in the GOA, it’d be cool if
we could include the Aleutian samples too. Obviously, we’ll want to
address those few instances from Aghiyuk, Shumagin, and Yunaska, and
ideally we aggregate them into one or two groups. We also see relatively
small sample sizes from Bristol Bay and from East Beaufort, which may or
may not be prohibitive in conducting meaningful tests. One other
consideration is the couple of samples along the Bering Strait coast
which are lumped together with a larger concentration of samples from
South Chukchi.
Some of our first analyses should see if the more isolated samples
are different from the other samples. If not, then we can aggregate. If
yes, then we should report any significant tests.
Temporal
distribution
Next we’ll want to take a look at how our samples distribute
throughout various time periods. This will give us a good idea of how
well our samples may or may not overlap- particularly, we’ll want to see
overlaps in years and months for better comparisons of the catch
data.
# First create a df specifically containing at time variables
times = visits.1 %>%
select(VisitID, Date) %>%
mutate(Year = year(Date),
Month = month(Date, label = TRUE),
Week = week(Date),
Day = yday(Date))
# Year
times %>%
count(Year) %>%
ggplot(., aes(x = Year, y = n)) +
geom_col() +
geom_text(aes(label = n), vjust = -0.5, color = "blue") +
labs(x = NULL, y = NULL, title = "No. samples per Year")

# Year without 1976
times %>%
filter(Year > 1980) %>%
count(Year) %>%
ggplot(., aes(x = Year, y = n)) +
geom_col() +
geom_text(aes(label = n), vjust = -0.5, color = "blue") +
labs(x = NULL, y = NULL, title = "No. samples per Year without 1976")

# Month
times %>%
count(Month) %>%
ggplot(., aes(x = Month, y = n)) +
geom_col() +
geom_text(aes(label = n), vjust = -0.5, color = "blue") +
labs(x = NULL, y = NULL, title = "No. samples per Month")

# Week
times %>%
count(Week) %>%
ggplot(., aes(x = Week, y = n)) +
geom_col() +
geom_text(aes(label = n), hjust = -0.15, angle = 90, color = "blue") +
labs(x = NULL, y = NULL, title = "No. samples per Week")

# Day of Year
times %>%
count(Day) %>%
distinct() %>%
ggplot(., aes(x = Day, y = n)) +
geom_col() +
labs(x = NULL, y = NULL, title = "No. samples per Day of Year")

By year, we see a large variability in number of samples, as well as
a lone 1976 year which I recognize to be Blackburn’s dataset from Lower
Cook Inlet. That 1976 is an interesting dataset that could be useful for
a look at catches over time in that specific area, but it’ll need to be
excluded from any other comparisons. The lowest number of samples occur
in 2010, 2020, and 2021. We may want to pay close attention to these
years in case they show up as outliers. It seems that 1996-2000 is a
period of heavy sampling, followed by the mid 2010s and somewhat active
year in 2006.
By month, we see an obvious uptick during the summer which makes
sense given winter conditions along most of Alaska’s coast (light, ice,
etc.). March and October are interesting months because of the potential
for impacts on fishes during years with warmer shoulder seasons.
November thru February will likely be removed for our purposes. Our key
months look to be June, July and August, with possible inclusion of
April, May, and September.
It’s interesting if we look at the by-week and by-day graphs, we see
a dip in sampling around mid-June/early-July. Not sure why this is-
maybe related to more targeting of juvenile salmonids in early June, or
maybe so reduced effort around the 4th of July holiday.
Year & month by
region
Let’s now see how our samples overlap by Region and Year, and by
Region and Month. For these purposes, let’s combine the Aleutians into
one group for now, and remove the 1976 data.
# Samples by Year and Region,
left_join(filter(times, Year > 1980),
select(visits.1, VisitID, Region), by = "VisitID") %>%
mutate(Region = case_when(str_detect(Region, "Aleutians") ~ "Aleutians",
!str_detect(Region, "Aleutians") ~ Region)) %>%
ggplot(aes(x = Date, y = Region, color = Region)) +
geom_boxplot() +
geom_jitter(size = 0.5, alpha = 0.75) +
stat_summary(geom = "text", vjust = -1.9, color = "black",
fun.data = function(x) {
return(c(y = median(x), label = length(x)))
}) +
scale_color_brewer(palette = "Spectral") +
scale_x_date(date_labels = "%y",
date_breaks = "2 years") +
labs(x = "Year", y = "Region",
title = "Samples by Year and Region",
subtitle = "No. samples centered over median") +
theme_minimal() +
theme(legend.position = "none")

# Samples by Month and Region,
left_join(filter(times, Year > 1980),
select(visits.1, VisitID, Region), by = "VisitID") %>%
mutate(Region = case_when(str_detect(Region, "Aleutians") ~ "Aleutians",
!str_detect(Region, "Aleutians") ~ Region)) %>%
ggplot(aes(x = Month, y = Region, color = Region)) +
geom_boxplot() +
geom_jitter(size = 0.5, alpha = 0.75) +
stat_summary(geom = "text", vjust = -1.9, color = "black",
fun.data = function(x) {
return(c(y = median(x), label = length(x)))
})+
scale_color_brewer(palette = "Spectral") +
labs(x = "Month", y = "Region",
title = "Samples by Month and Region",
subtitle = "Excluding 1976; no. samples labelled by month") +
theme_minimal() +
theme(legend.position = "none")

Interesting that each region’s samples center on a different year. At
a glance, I see the most overlap in 2006 where the Aleutians and both
GOA regions look to have similar sample densities, plus there is a
smattering of Chukchi/Beaufort sampling too. In 2009, the Bristol Bay
samples may be compared with both GoA regions and the Chukchi/Beaufort,
although the samples look more sparse across the regions. And in 2013,
the Chukchi/Beaufort has good overlap with both GOA regions again. I see
nice periods of comparison between SEAK and SCAK, but there is also a
concerning difference in yearly distribution of samples between the two
regions. Depending on how important year effects appear- we may need to
trim the data for better comparisons.
By month, we see that August contains samples from all regions. June
is the center for SEAK and the Aleutians, July for SCAK, and August for
Chukchi/Beaufort. Best comparisons from this monthly view may be an
August (or lumped July + August) comparison of all Regions. Also, a June
(or lumped June thru August) comparison of GOA and the Aleutians would
be good. And, we should be able to nicely compare SEAK and SCAK from May
to September, potentially including April.
For now, we’ll hold off on excluding any of the data. It’ll be better
to revisit these considerations after deciding which research questions
to tackle, so subsets of the data can be made specific to each one.
Mesh Size and
Replicates
Let’s make similar visuals as before, but now focus on Mesh Size and
Replicates in space and time. First, we can re-map the samples to color
by Mesh Size and size of points relative Replicates (large dots = more
replicates).
# Palette function to color markers
palette.mesh = colorFactor(palette = brewer.pal(n = visits.1$MeshSize %>% n_distinct(),
name = 'Spectral'),
domain = factor(visits.1$MeshSize))
# Map
leaflet(visits.1) %>%
addTiles() %>%
addCircleMarkers(lng = ~Lon, lat = ~Lat,
radius = ~(sqrt(Replicates*15)),
color = ~palette.mesh(MeshSize),
fillColor = ~palette.mesh(MeshSize),
popup = ~VisitID,
stroke = FALSE) %>%
addLegend(position = "bottomright",
pal = palette.mesh, values = ~MeshSize,
title = "Mesh Size (mm)",
opacity = 0.75)
I have an issue discerning among the seven different sizes since
those warmer colors do not diverge well. Although there are some
patterns to make note of: the largest mesh size of 12.7 only occurs in a
small area of SEAK, the 10 mm samples similarly only occur with the 12.7
mm samples (likely the Lundstrom et
al. 2022 gear comparison), and the smallest size at 3 mm only occurs
in Cook Inlet. I don’t see any obvious spatial patterns in Replicates,
although this may not be the best view of it.
Let’s see the frequency of samples for both variables:
# Table view
table(visits.1$MeshSize)
##
## 3 3.2 6 6.4 9.5 10 12.7
## 436 821 286 35 82 59 148
table(visits.1$Replicates)
##
## 1 2 3 4 5 6 7 8 9 10 12
## 665 533 334 142 60 90 19 21 1 1 1
There are more 12.7 mm samples than I would have guessed which is a
shame because if they are completely different then we lose a lot of
samples. I am wondering if sizes are accurate- I would think that 3 mm
and 3.2 mm are effectively similar in practice. I am also wondering if
some projects report, say 3 mm instead of 3.2 mm, because of rounding. I
would assume that the nets used were manufactured in the US, which would
mean that specifications are given in standard not metric. Let’s do a
quick check on how typical mesh sizes convert from inches to
millimeters.
# Function based on inch to millimeter conversion
in_to_mm = function (x) {
return(y = 25.4 * x)
}
# Typical mesh sizes in inches
sizes = c((1/8), (1/4), (3/8), (1/2), (5/8), (3/4))
# Convert to millimeters
in_to_mm(sizes)
## [1] 3.175 6.350 9.525 12.700 15.875 19.050
There is obviously some funny rounding happening in the data. I do
not see an issue by lumping mesh sizes that are within one millimeter.
Even if the nets were actually different by fractions of a millimeter, I
don’t think it would affect the selectivity of fishes all that much-
especially considering that most of these researchers were capturing
fish to be measured to the nearest millimeter.
Let’s see that map again with this in mind:
# Palette function for binned sizes
palette.mesh.bin = colorBin(palette = brewer.pal(n = 4, name = 'Spectral'),
domain = visits.1$MeshSize %>% unique(),
bins = c(0, 4, 7, 11, 13))
# Map
leaflet(visits.1) %>%
addTiles() %>%
addCircleMarkers(lng = ~Lon, lat = ~Lat,
radius = ~(sqrt(Replicates*15)),
color = ~palette.mesh.bin(MeshSize),
fillColor = ~palette.mesh.bin(MeshSize),
popup = ~VisitID,
stroke = FALSE) %>%
addLegend(position = "bottomright",
colors = c(palette.mesh.bin(3),
palette.mesh.bin(6),
palette.mesh.bin(9),
palette.mesh.bin(12)),
values = ~MeshSize,
title = "Mesh Size (mm)",
opacity = 0.75,
labels = c("3 or 3.2", "6 or 6.4", "9.5 or 10", "12.7"))
Much easier to read! I see some concerning patterns we’ll want to
investigate further as we go. The majority of samples appear to be using
the 3.2 mm size, including both Arctic groups that seem to use it
exclusively. There is a large density of 6.4 mm samples in Northern SEAK
and throughout the Aleutians. The same issues are visible concerning the
two larger mesh sizes. We should do a comparison of 3.2 mm and 6.4 mm to
see if there are any significant differences in catch.
With the simpler color scheme, I am also noticing the difference in
Replicates a little easier. Just looking at GOA and Aleutian samples, I
see that many of the 6.4 mm samples are also low-Replicate samples.
Although, many of our samples only contain one replicate so this may
just be something I’m seeing and not actually a concern.
Let’s take a look at how these variables in graphical format. I’ll go
ahead and aggregate similar mesh sizes and re-classify the both
variables as factors, and add in variables for year and month.
visits.2 = mutate(visits.1,
Replicates = as_factor(Replicates),
# Combine similar mesh sizes to the tenth decimal
MeshSize = case_when(MeshSize < 4 ~ 3.2,
MeshSize > 4 & MeshSize < 7 ~ 6.4,
MeshSize > 7 & MeshSize < 11 ~ 9.5,
MeshSize == 12.7 ~ 12.7) %>%
as.factor()) %>%
# Add temporal variables
left_join(select(times, VisitID, Year, Month), by = "VisitID")
# Samples by MeshSize and Year,
filter(visits.2, Year > 1989) %>%
ggplot(aes(x = Date, y = MeshSize, color = MeshSize)) +
geom_boxplot() +
geom_jitter(size = 0.5, alpha = 0.75) +
stat_summary(geom = "text", vjust = -3, color = "black",
fun.data = function(x) {
return(c(y = median(x), label = length(x)))
}) +
scale_color_brewer(palette = "Spectral") +
scale_x_date(date_labels = "%y",
date_breaks = "2 years") +
labs(x = "Year", y = "Mesh Size (mm)",
title = "Samples by Year and Mesh Size",
subtitle = "Excluding 1976; no. samples centered over median") +
theme_minimal() +
theme(legend.position = "none")

# Samples by Month and MeshSize,
filter(visits.2, Year > 1989) %>%
ggplot(aes(x = Month, y = MeshSize, color = MeshSize)) +
geom_boxplot() +
geom_jitter(size = 0.5, alpha = 0.75) +
stat_summary(geom = "text", vjust = -3, color = "black",
fun.data = function(x) {
return(c(y = median(x), label = length(x)))
})+
scale_color_brewer(palette = "Spectral") +
labs(x = "Month", y = "Mesh Size (mm)",
title = "Samples by Month and Mesh Size",
subtitle = "Excluding 1976; no. samples labelled by month") +
theme_minimal() +
theme(legend.position = "none")

# Samples by Replicates and Year,
filter(visits.2, Year > 1989) %>%
ggplot(aes(x = Date, y = Replicates, color = Replicates)) +
geom_boxplot() +
geom_jitter(size = 0.5, alpha = 0.75) +
stat_summary(geom = "text", vjust = -1, color = "black",
fun.data = function(x) {
return(c(y = median(x), label = length(x)))
}) +
scale_color_brewer(palette = "Spectral") +
scale_x_date(date_labels = "%y",
date_breaks = "2 years") +
labs(x = "Year", y = "Replicates",
title = "Samples by Year and Replicates",
subtitle = "Excluding 1976; no. samples centered over median") +
theme_minimal() +
theme(legend.position = "none")

# Samples by Replicates and Month,
filter(visits.2, Year > 1989) %>%
ggplot(aes(x = Month, y = Replicates, color = Replicates)) +
geom_boxplot() +
geom_jitter(size = 0.5, alpha = 0.75) +
stat_summary(geom = "text", vjust = -1, color = "black",
fun.data = function(x) {
return(c(y = median(x), label = length(x)))
})+
scale_color_brewer(palette = "Spectral") +
labs(x = "Month", y = "Replicates",
title = "Samples by Month and Replicates",
subtitle = "Excluding 1976; no. samples labelled by month") +
theme_minimal() +
theme(legend.position = "none")

LS0tCnRpdGxlOiAiTk9BQSBOZWFyc2hvcmUgRmlzaCBBdGxhcywgRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNlcyIKYXV0aG9yOiAiQ2hyaXMgR3VvIgpkYXRlOiAiTGFzdCBjb21waWxlZCBvbiBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IFRSVUUKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IEZBTFNFCiAgICAgIHByaW50OiBGQUxTRQogICAgbnVtYmVyX3NlY3Rpb25zOiBUUlVFCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFCnRoZW1lOiAiZmxhdGx5IgotLS0KCmBgYHtyIGluY2x1ZGUgPSBGQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KG1lc3NhZ2UgPSBGQUxTRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KHdhcm5pbmcgPSBGQUxTRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KHNpemUgPSAic2NyaXB0c2l6ZSIpCmBgYAoKQnVpbHQgd2l0aCBSIHZlcnNpb24gYHIgZ2V0UnZlcnNpb24oKWAuCgojIEludHJvZHVjdGlvbgoKVGhlIHB1cnBvc2Ugb2YgdGhpcyBkb2N1bWVudCBpcyB0byBtYWtlIG9wZW4gYW5kIHNoYXJlLWFibGUgdGhlIHJlc2VhcmNoIG1ldGhvZHMgdXNlZCBmb3IgbXkgZGlzc2VydGF0aW9uIG9uIG5lYXJzaG9yZSBmaXNoIGNvbW11bml0aWVzIGluIEFsYXNrYSB3b3JraW5nIHRvd2FyZHMgYSBQaEQgaW4gbWFyaW5lIGJpb2xvZ3kgYXQgdGhlIFVuaXZlcnNpdHkgb2YgQWxhc2thIEZhaXJiYW5rcy4gSGVyZSwgSSBjb3ZlciBzdGVwcyBvZiB0aGUgZGF0YSBwcmVwYXJhdGlvbiBmb3IgbXkgc2Vjb25kIGFuZCB0aGlyZCBjaGFwdGVycyBjb25jZXJuaW5nIHNwYXRpYWwgYW5kIHRlbXBvcmFsIGRpc3RyaWJ1dGlvbnMgb2YgbmVhcnNob3JlIGZpc2hlcyBhY3Jvc3MgdGhlIHN0YXRlLiBUaGlzIGFuZCBvdGhlciBmaWxlcyBjYW4gYmUgYWNjZXNzZWQgdmlhIHRoZSBLYWNoZW1hayBCYXkgTmF0aW9uYWwgRXN0dWFyaW5lIFJlc2VhcmNoIFJlc2VydmUncyBnaXRodWIgW25lYXJzaG9yZSBmaXNoIHJlcG9zaXRvcnldKGh0dHBzOi8vZ2l0aHViLmNvbS9rYm5lcnIvbmVhcnNob3JlLWZpc2gpLgoKSW4gdGhpcyBkb2N1bWVudCBJIHNoYXJlIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzZXMgY29uZHVjdGVkIG9uIHRoZSBOT0FBIE5lYXJzaG9yZSBGaXNoIEF0bGFzIChORkEpIGRhdGFiYXNlLiBUaGUgTkZBIGRhdGFiYXNlIGNhbiBiZSBmb3VuZCBoZXJlLCA8aHR0cHM6Ly9hbGFza2FmaXNoZXJpZXMubm9hYS5nb3YvbWFwcGluZy9zei8+LiBOYW1lbHksIHRoaXMgZG9jdW1lbnQgY29udGFpbnMgdGhlIHN0ZXBzIHRha2VuIGFmdGVyIGNsZWFuaW5nL3dyYW5nbGluZyByYXcgZGF0YS4gSW4gcGFydGljdWxhciBJIHByb2R1Y2UgdmFyaW91cyB2aXN1YWxpemF0aW9ucyBvZiB0aGUgZGF0YSBpbiBzcGFjZSBhbmQgdGltZS4gSW5pdGlhbCB3cmFuZ2xlIHN0ZXBzIGNhbiBiZSB2aWV3ZWQgYXQgdGhpcyBbUnB1YnMgcGFnZV0oaHR0cHM6Ly9ycHVicy5jb20vY2hndW8xLzExODg2MTQpIGFuZCBpdHMgZGF0YSBvYmplY3RzIGFyZSBzb3VyY2VkIGJlbG93IChmaWxlICJORkEucmRhIikuCgojIyBTZXQgdXAKCkxvYWQgcmVxdWlyZWQgcGFja2FnZXMsIGRlZmluZSBkaXJlY3RvcnksIHNldCBvcHRpb25zLCBzb3VyY2UvbG9hZCBmaWxlczoKCmBgYHtyIHJlc3VsdHMgPSAnaGlkZSd9CiMgUGFja2FnZXMKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkobGVhZmxldCkKbGlicmFyeShSQ29sb3JCcmV3ZXIpCgojIERpcmVjdG9yeQp3ZCA9IGhlcmUoKQpkaXJzID0gd2QgJT4lIGxpc3QuZmlsZXMoKSAlPiUgc3RyX3N1YnNldChwYXR0ZXJuID0gIl5SRUFETUV8XkxJQ0VOU0V8Lm1kJHwuUnByb2okIiwgbmVnYXRlID0gVFJVRSkKZm9yIChpIGluIHNlcV9hbG9uZyhkaXJzKSkgewogIG5hbWUgPSBzdHJfcmVwbGFjZV9hbGwoZGlyc1tpXSwgIl4iLCAiZGlyLiIpCiAgcGF0aCA9IHN0cl9yZXBsYWNlX2FsbChkaXJzW2ldLCAiXiIsIHN0cl9jKHdkLCAiLyIpKQogIGFzc2lnbihuYW1lLCBwYXRoKQogIHJtKG5hbWUsIHBhdGgsIGkpCn0KCiMgT3B0aW9ucwoKIyBTb3VyY2UvTG9hZApsb2FkKGZpbGUucGF0aChkaXIuZGF0YSwgIk5GQV93cmFuZ2xlZC5yZGEiKSkgIyB3cmFuZ2xlZCBkYXRhCmBgYAoKIyMgQmFja2dyb3VuZCBhbmQgb2JqZWN0aXZlcwoKQmFzZWQgb24gbXkgb3duIHJlc2VhcmNoIGFuZCByZWxhdGVkIGxpdGVyYXR1cmUsIEkgY2FuIGJyb2FkbHkgaW50ZXJwcmV0IHRoZXNlIGJlYWNoIHNlaW5lIGRhdGEgaW4gYSBzcGF0aW90ZW1wb3JhbCBjb250ZXh0LiBEZXBlbmRpbmcgb24gd2hlbiAodGltZSBvZiB5ZWFyKSBhbmQgd2hlcmUgKGxvY2F0aW9uIGFuZCBoYWJpdGF0KSwgSSBoYXZlIGEgZ2VuZXJhbCBzdHJ1Y3R1cmUgaW4gbWluZCBvZiB0aGUgZGl2ZXJzaXR5IG9mIHRoZSBjb21tdW5pdHkuIERlcGVuZGluZyBvbiB3aG8ncyB0aGVyZSwgSSBoYXZlIGEgcm91Z2ggZ3Vlc3Mgb2YgdGhlIHJlbGF0aXZlIGFidW5kYW5jZSBvZiBlYWNoIGNvbW11bml0eSBtZW1iZXIgKGF0IGxlYXN0IGZvciB0aGUgbW9yZSBjb21tb25seSBjYXVnaHQgb25lcykuIE15IGhvcGUgd2l0aCB3b3JraW5nIHdpdGggdGhlIE5GQSBkYXRhIGlzIHRoYXQgdGhpcyBicm9hZCB1bmRlcnN0YW5kaW5nIGNhbiBiZSBmb3JtYWxseSB0ZXN0ZWQgd2l0aCBpbmZlcmVuY2UgYW5kIHN0YXRpc3RpY3MsIGFuZCB0aGF0IG1vcmUgaW5mb3JtYXRpdmUgcmVzZWFyY2ggcXVlc3Rpb25zIGNhbiBiZSBhbnN3ZXJlZC4KCkZpbmRpbmdzIGZyb20gb3RoZXIgbmVhcnNob3JlIGZpc2ggcmVzZWFyY2hlcnMgbGFyZ2VseSBhZ3JlZSB0aGF0IHNlYXNvbmFsaXR5IChvciBzb21lIHJlbGF0ZWQgZW52aXJvbm1lbnRhbCBjb25kaXRpb24pIGlzIGEgc3Ryb25nIHByZWRpY3RvciBvZiBjb21tdW5pdHkgb3Igc3BlY2llcyBwcmVzZW5jZS4gSW50ZXJhbm51YWwgZGlmZmVyZW5jZXMgY2FuIGV4aGliaXQgd2lkZSB2YXJpYWJpbGl0eSBhbmQgc2hvdWxkIGJlIGFjY291bnRlZCBmb3Igd2hlbmV2ZXIgcG9zc2libGUuIEFuZCBhdCBsYXJnZXIgdGltZS1zY2FsZXMgKGUuZy4sIGRlY2FkYWwpLCBjb21tdW5pdGllcyBleGhpYml0IGNoYW5nZXMgd2hpY2ggbWF5IHJlbGF0ZSB0byByZWdpbWUgc2hpZnRzIG9jY3VycmluZyBtb3JlIGJyb2FkbHkgdGhhbiB0aGUgbmVhcnNob3JlLgoKU3BhdGlhbGx5LCBsYXJnZS1zY2FsZSAocmVnaW9uYWwpIGVmZmVjdHMgYXBwZWFyIHRvIGJlIGFzIG9yIG1vcmUgaW1wb3J0YW50IHRoYW4gc3ViLXJlZ2lvbmFsIG9yIGxvY2FsLXNjYWxlIGVmZmVjdHMuIEhvd2V2ZXIsIG1hbnkgc3R1ZGllcyBhbHNvIGZpbmQgc2lnbmlmaWNhbnQgcmVsYXRpb25zaGlwcyBpbiBjb21tdW5pdHkgcmVzcG9uc2UgYXQgdGhlc2Ugc21hbGxlciBzY2FsZXMuIExpa2VseSwgdGhlIG1vc3QgYXBwcm9wcmlhdGUgc3BhdGlhbCBjb25zaWRlcmF0aW9uIGRlcGVuZHMgb24gdGhlIHF1ZXN0aW9uIGJlaW5nIGFza2VkLiBTbyBtYXliZSBhIG1vcmUgYXBwcm9wcmlhdGUgcXVlc3Rpb24gdG8gYXNrIG9mIHRoZSBORkEgZGF0YSBpcyBpZiB0aGVyZSBhbnkgc2lnbmlmaWNhbnQgc3BhdGlhbCBzY2FsZXMgZGlzY2VybmlibGUgaW4gdGhlIGRhdGEsIGFuZCBhbHNvIGhvdyBzaG91bGQgd2UgYWRkcmVzcyB0aG9zZSBzY2FsZXMgaW4gZnV0dXJlIHJlc2VhcmNoLCBzdWNoIGFzIHN0dWRpZXMgb24gc3Vic2V0cyBvZiB0aGUgdGF4YSBvciBoYWJpdGF0IG1hbmFnZW1lbnQgY29uc2lkZXJhdGlvbnMuCgpJJ2xsIHN0YXJ0IGJ5IGV4cGxvcmluZyB0aGUgc3RydWN0dXJlIG9mIG91ciAndmlzaXRzJyBkYXRhZnJhbWUsIGFuZCB0aGVuIEknbGwgbW92ZSBvbiB0byB2aXN1YWxpemluZyB0aGUgaW5mb3JtYXRpb24gZGVyaXZlZCBmcm9tIG91dCAnY2F0Y2gnIGRhdGFmcmFtZS4KCiMgRXhwbG9yaW5nIHZpc2l0IGRhdGEKCiMjIFN1bW1hcnkgb2YgdmlzaXRzCgpSZW1lbWJlciB0aGF0IGluIHRoZSBkYXRhIHdyYW5nbGluZyBzdGFnZSwgd2UgY3JlYXRlZCBhIG5ldyBzYW1wbGUgaWRlbnRpZmllciBiYXNlZCBvbiBzaXRlIGFuZCBkYXRlIHdoaWNoIHdlIGNhbGxlZCBWaXNpdElELiBMZXQncyB0YWtlIGEgbG9vayBhdCB0aGUgdmFyaWFibGVzIGFzc29jaWF0ZWQgd2l0aCBlYWNoIFZpc2l0SUQ6CgpgYGB7cn0KZ2xpbXBzZSh2aXNpdHMpCmBgYAoKRHVyaW5nIHRoZSB3cmFuZ2xpbmcgc3RhZ2UsIEkgZGVjaWRlZCB0aGF0IFJlcGxpY2F0ZXMgYW5kIE1lc2hTaXplIHNob3VsZCBiZSB0aGUgbWFpbiBjb3ZhcmlhdGVzIHRoYXQgbmVlZGVkIGNvbnNpZGVyYXRpb24uIEF0IHRoaXMgcG9pbnQgdGhleSBhcmUgY2xhc3NlZCBhcyBpbnRlZ2Vycy9udW1iZXJzLCBidXQgd2Ugd2lsbCBwcm9iYWJseSB3YW50IHRoZW0gdG8gYmUgZmFjdG9ycyBpbnN0ZWFkLiBDbHVzdGVyIGlzIGEgYnlwcm9kdWN0IG9mIGNsdXN0ZXJpbmcgc29tZSBzaXRlcyB0b2dldGhlciwgc28gaXQgbWF5IG5vdCBiZSBuZWVkZWQgaWYgd2UncmUgdXNpbmcgTGF0L0xvbiBhcyBvdXIgcHJpbWFyeSBleHBsYW5hdG9yeSB2YXJpYWJsZS4gU3RpbGwsIGl0IGNvdWxkIGJlIGEgdXNlZnVsIGdyb3VwaW5nIGZhY3RvciBsYXRlciBvbi4gRGF0ZSB3aWxsIGxpa2VseSBiZSBtdXRhdGVkIGludG8gbXVsdGlwbGUgYWRkaXRpb25hbCBwZXJpb2RzIChkYXkgb2YgeWVhciwgbW9udGgsIHllYXIpIHRvIHNlZSBpZiBhbnkgb2YgdGhvc2UgZmFjdG9ycyBhcmUgdXNlZnVsIGluIGV4cGxhaW5pbmcgZmlzaCBkYXRhLiBXZSdsbCBhZGRyZXNzIGVkaXRzIHRvIHRoZXNlIHZhcmlhYmxlcyBhcyB0aGV5IGNvbWUgdXAgaW4gb3VyIGV4cGxvcmF0aW9uLgoKIyMgU3BhdGlhbCBkaXN0cmlidXRpb24KCmBgYHtyfQpsZWFmbGV0KHZpc2l0cykgJT4lIAogIGFkZFRpbGVzKG9wdGlvbnMgPSB0aWxlT3B0aW9ucyhtaW5ab29tID0gMy41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6SW5kZXggPSAwLjUpKSAlPiUKICBzZXRWaWV3KGxhdCA9IDY1LCBsbmcgPSAtMTUyLCB6b29tID0gMy41KSAlPiUKICBhZGRTaW1wbGVHcmF0aWN1bGUoaW50ZXJ2YWwgPSA1KSAlPiUgIAogIGFkZENpcmNsZU1hcmtlcnMobG5nID0gfkxvbiwgbGF0ID0gfkxhdCwKICAgICAgICAgICAgICAgICAgIHN0cm9rZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgcG9wdXAgPSB+VmlzaXRJRCwKICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJPcHRpb25zID0gbWFya2VyQ2x1c3Rlck9wdGlvbnMoKSkKYGBgCgpJbiB0aGUgbWFwIGFib3ZlIHdlIGNhbiB2aWV3IGFsbCBvZiBvdXIgc2FtcGxlcyBmcm9tIGFjcm9zcyBBbGFza2EuIExlYWZsZXQgb3B0aW9ucyBhcmUgbmljZSBiZWNhdXNlIHlvdSBjYW4gb3B0aW9uYWxseSBncm91cCBzYW1wbGVzIG9uIHRoZSBtYXAgYW5kIHNob3cgYSBib3VuZGFyeSBwb2x5Z29uIG9mIHRoZSBhcmVhIHRoZXkgY292ZXIgd2hlbiB5b3UgaG92ZXIgb3ZlciB0aGVpciBpY29uLiBBdCB0aGUgbWluaW11bSB6b29tIGxldmVsICgzLjUpLCB3ZSBzZWUgdGhlIGxhcmdlc3QgZ3JvdXAgc3Bhbm5pbmcgbmVhcmx5IGFsbCBvZiBTb3V0aGVhc3QgQWxhc2thLCBmb2xsb3dlZCBieSBhIGdyb3VwIGluIFNvdXRoY2VudHJhbCB0aGF0IGNvdmVycyBQcmluY2UgV2lsbGlhbSBTb3VuZCwgQ29vayBJbmxldCwgYW5kIHRoZSBub3J0aGVybiBoYWxmIG9mIEtvZGlhayBJc2xhbmQuIFRoZSB0aGlyZCBsYXJnZXN0IGdyb3VwIGZvcm1zIGEgbXVjaCBzbWFsbGVyIHBvbHlnb24gYXJlYSBhcm91bmQgVXRxaWFndmlrLiBGcm9tIHRoZXJlLCB3ZSBzZWUgZXZlbiBzbWFsbGVyIGdyb3VwcyBmcm9tIHRoZSBFYXN0ZXJuIEJlYXVmb3J0IFNlYSBhcm91bmQgS2FrdG92aWssIHRoZSBCZXJpbmcgU3RyYWl0IGFuZCBTb3V0aGVybiBDaHVrY2hpIFNlYSBuZWFyIEtvdHplYnVlLCBhbmQgQnJpc3RvbCBCYXkuIFRoZXJlIGFyZSBhbHNvIHR3byBncm91cHMgZnJvbSB0aGUgQWxhc2thIFBlbmluc3VsYSBhbmQgQWxldXRpYW4gSXNsYW5kcywgb25lIGZvY3VzZWQgYXJvdW5kIEFkYWsgYW5kIGFub3RoZXIgc3Bhbm5pbmcgZnJvbSBTYW5kIFBvaW50IHRvIFVuYWxhc2thLiBXZSBjYW4gc2VlIGhvdyBzdWJzZXRzIG9mIHRoZSBzYW1wbGVzIGNoYW5nZSBieSB6b29taW5nIGluLiBXaGVuIHRoZXJlIGFyZSBzaW5nbGUgc2FtcGxlcyBpbiB2aWV3LCBob3ZlcmluZyBvdmVyIHRob3NlIHdpbGwgdGVsbCB1cyBpdHMgVmlzaXRJRCBuYW1lLgoKT2J2aW91c2x5LCB0aGlzIHZpc3VhbGl6YXRpb24gb2YgdGhlIGRhdGEgaXMgbm90IHBlcmZlY3QgYW5kIHByZXR0eSByb3VnaC0gbm90ZSB0aGF0IHRoZSBncm91cHMgYXJlIGZvcm1lZCBieSB0aGUgb3ZlcmxhcCBvZiBzYW1wbGVzIGJhc2VkIG9uIHBpeGVsIHJhZGl1cyAoMTApLiBGb3IgZXhhbXBsZSwgdGhlIHBvbHlnb24gb2Ygc2FtcGxlcyBmcm9tIEJyaXN0b2wgQmF5IGF0IHRoZSBtaW5pbXVtIHpvb20gbGV2ZWwgYWN0dWFsbHkgY3Jvc3NlcyB0aGUgQWxhc2thIFBlbmluc3VsYSB0byBpbmNsdWRlIGEgc2FtcGxlIGZyb20gQWdoaXl1ayBJc2xhbmQuIEFsdGhvdWdoLCB0aGUgbWFwIGlzIHVzZWZ1bCBpbiBnYWluaW5nIGEgZ2VuZXJhbCB1bmRlcnN0YW5kaW5nIG9mIHRoZSBleGlzdGluZyBjbHVzdGVycyBvZiBzYW1wbGVzIHdpdGhpbiB0aGUgTkZBIGRhdGFiYXNlLgoKIyMgUmVnaW9ucwoKV2UgbWF5IHdhbnQgdG8gZGVmaW5lIGEgc3BhdGlhbCBmYWN0b3IgYmFzZWQgb24gdGhlc2Ugcm91Z2ggZ3JvdXBpbmdzIGFzIGEgc3RhcnRpbmcgcGxhY2UgdG8gc2VlIGlmIHRoZSBzbWFsbGVyLCBtb3JlIGlzb2xhdGVkIGdyb3VwcyBzaG91bGQgYmUgbHVtcGVkIHdpdGggb3RoZXIgZ3JvdXBzIG9yIG5vdC4gQWN0dWFsbHksIHRoZSBORkEgYWxyZWFkeSBoYXMgYSBSZWdpb24gY2xhc3NpZmllciBwZXIgc2l0ZSwgYnV0IHRoZSByZWFzb24gSSBkbyBub3Qgd2FudCB0byB1c2UgaXQgaXMgYmVjYXVzZSB0aGV5IGxpbmtlZCBSZWdpb24gdG8gU2l0ZUlELiBXaGVuIHdlIGNyZWF0ZWQgb3VyIG5ldyBWaXNpdElELCBzb21lIHNhbXBsZXMgbm93IGNvbnRhaW5lZCB0d28gUmVnaW9uIGxhYmVscy0gdGhlc2Ugd2VyZSBtb3N0bHkgY2FzZXMgZnJvbSBhcm91bmQgVXRxaWFndmlrIHdoZXJlIHNvbWUgd2VyZSBsYWJlbGxlZCBhcyBDaHVja2NoaSBhbmQgb3RoZXJzIGFzIEJlYXVmb3J0IGJ1dCBhY3R1YWxseSBvY2N1cnJlZCBvbiB0aGUgc2FtZSBkYXkgYW5kIHdpdGhpbiBhIHZlcnkgc2hvcnQgZGlzdGFuY2Ugb2YgZWFjaCBvdGhlci4KCkluc3RlYWQgb2YgdXNpbmcgdGhlIHRoZSBnaXZlbiByZWdpb25hbCBjbGFzc2VzLCBsZXQncyBqdXN0IG1ha2Ugb3VyIG93biB2YXJpYWJsZSBjYWxsZWQgJ1JlZ2lvbicgYW5kIGFkZCBpdCB0byB0aGUgb3VyIHZpc2l0cyBkZjoKCmBgYHtyfQojIFN0YXJ0IHdpdGggZXZlbnRzIHNvIHRoYXQgd2UgY2FuIG1ha2UgdXNlIG9mIExvY2F0aW9uIGluZm8gZm9yIHVuaXF1ZSBjYXNlcywKcmVnaW9ucyA9IGV2ZW50cyAlPiUKICBzZWxlY3QoRXZlbnRJRCwgVmlzaXRJRCwgTGF0LCBMb24sIExvY2F0aW9uKSAlPiUKICBtdXRhdGUoUmVnaW9uID0gY2FzZV93aGVuKExhdCA+IDY5ICYgTGF0IDwgODAgJiBMb24gPiAtMTUwICYgTG9uIDwgLTE0MCB+ICJCZWF1Zm9ydCBFYXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhdCA+IDY5ICYgTGF0IDwgODAgJiBMb24gPiAtMTYwICYgTG9uIDwgLTE1MCB+ICJDaHVrY2hpL0JlYXVmb3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhdCA+IDY1ICYgTGF0IDwgNjkgJiBMb24gPiAtMTcwICYgTG9uIDwgLTE2MCB+ICJDaHVrY2hpIFNvdXRoIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhdCA+IDU3ICYgTGF0IDwgNjAgJiBMb24gPiAtMTY1ICYgTG9uIDwgLTE1NSB+ICJCcmlzdG9sIEJheSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYXQgPiA1MCAmIExhdCA8IDU1ICYgTG9uID4gLTE4MCAmIExvbiA8IC0xNzUgfiAiQWxldXRpYW5zIEFkYWsiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTGF0ID4gNTAgJiBMYXQgPCA1NSAmIExvbiA+IC0xNzAgJiBMb24gPCAtMTY1IH4gIkFsZXV0aWFucyBVbmFsYXNrYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYXQgPiA1NSAmIExhdCA8IDY1ICYgTG9uID4gLTE1NSAmIExvbiA8IC0xNDUgfiAiR09BIFNvdXRoY2VudHJhbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYXQgPiA1MyAmIExhdCA8IDYxICYgTG9uID4gLTE0OCAmIExvbiA8IC0xMzAgfiAiR09BIFNvdXRoZWFzdCIpKQoKIyBDaGVjayB3aGljaCBzYW1wbGVzIHdlIG1pc3NlZCwKZmlsdGVyKHJlZ2lvbnMsIGlzLm5hKFJlZ2lvbikpCgojIExldCdzIGFkZHJlc3MgdGhvc2UgdXNpbmcgTG9jYXRpb24sCnJlZ2lvbnMgPSBtdXRhdGUocmVnaW9ucywKICAgICAgIFJlZ2lvbiA9IGNhc2Vfd2hlbighaXMubmEoUmVnaW9uKSB+IFJlZ2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpcy5uYShSZWdpb24pICYgc3RyX2RldGVjdChMb2NhdGlvbiwgIll1bmFza2EiKSB+ICJBbGV1dGlhbnMgWXVuYXNrYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaXMubmEoUmVnaW9uKSAmIHN0cl9kZXRlY3QoTG9jYXRpb24sICJBZ2hpeXVrIikgfiAiQWxldXRpYW5zIEFnaGl5dWsiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGlzLm5hKFJlZ2lvbikgJiBzdHJfZGV0ZWN0KExvY2F0aW9uLCAiU2h1bWFnaW4iKSB+ICJBbGV1dGlhbnMgU2h1bWFnaW4iKSkKCiMgQ2hlY2sgYWdhaW4gKHNob3VsZCBiZSAwKSwKZmlsdGVyKHJlZ2lvbnMsIGlzLm5hKFJlZ2lvbikpICU+JSBucm93KCkKYGBgCgpOb3cgbGV0J3MgYWRkIFJlZ2lvbiBhcyBhIGZhY3RvciB0byBvdXIgdmlzaXRzIGRmLCBhbmQgc2hvdyBpdCBvbiBhIG1hcC4gU2luY2Ugd2UncmUgbWFuaXB1bGF0aW5nIG91ciBkYXRhIG9iamVjdHMgYWdhaW4sIGxldCdzIGFsc28gcmVuYW1lIHZpc2l0cyBzbyB0aGF0IHdlIGNhbiBrZWVwIHRyYWNrIG9mIG91ciBjaGFuZ2VzLgoKYGBge3J9CiMgQ2FsbCBvdXIgd3JhbmdsZWQgZGYgdmVyc2lvbiB2aXNpdHMuMCBhbmQgcmVtb3ZlIHRoZSBub24tdmVyc2lvbiAndmlzaXRzJyBpZiBpdCdzIHRoZXJlLAppZiAoInZpc2l0cyIgJWluJSBscygpKSBhc3NpZ24oInZpc2l0cy4wIiwgdmlzaXRzKQppZiAoInZpc2l0cyIgJWluJSBscygpKSBybSh2aXNpdHMpCgojIE1ha2UgUmVnaW9uIGEgZmFjdG9yIGFuZCBqb2luIGJ5IFZpc2l0SUQsCnZpc2l0cy4xID0gcmVnaW9ucyAlPiUKICBzZWxlY3QoVmlzaXRJRCwgUmVnaW9uKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIG11dGF0ZShSZWdpb24gPSBhcy5mYWN0b3IoUmVnaW9uKSkgJT4lCiAgbGVmdF9qb2luKHZpc2l0cy4wLCAuLCBieSA9ICJWaXNpdElEIikKCiMgRnVuY3Rpb24gZm9yIHJlZ2lvbmFsIHBhbGV0dGUKcGFsZXR0ZS5yZWdpb24gPSBjb2xvckZhY3RvcihwYWxldHRlID0gYnJld2VyLnBhbChuID0gdmlzaXRzLjEkUmVnaW9uICU+JSBuX2Rpc3RpbmN0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICdTcGVjdHJhbCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbiA9IGZhY3Rvcih2aXNpdHMuMSRSZWdpb24pKQoKIyBNYXAKbGVhZmxldCh2aXNpdHMuMSkgJT4lIAogIGFkZFRpbGVzKCkgJT4lCiAgYWRkQ2lyY2xlTWFya2VycyhsbmcgPSB+TG9uLCBsYXQgPSB+TGF0LAogICAgICAgICAgICAgICAgICAgY29sb3IgPSB+cGFsZXR0ZS5yZWdpb24oUmVnaW9uKSwKICAgICAgICAgICAgICAgICAgIGZpbGxDb2xvciA9IH5wYWxldHRlLnJlZ2lvbihSZWdpb24pLAogICAgICAgICAgICAgICAgICAgcG9wdXAgPSB+cGFzdGUoUmVnaW9uLCBWaXNpdElEKSwKICAgICAgICAgICAgICAgICAgIHN0cm9rZSA9IEZBTFNFKSAlPiUKICBhZGRMZWdlbmQocG9zaXRpb24gPSAidG9wcmlnaHQiLAogICAgICAgICAgICBwYWwgPSBwYWxldHRlLnJlZ2lvbiwgdmFsdWVzID0gflJlZ2lvbiwKICAgICAgICAgICAgdGl0bGUgPSAiUmVnaW9uIiwKICAgICAgICAgICAgb3BhY2l0eSA9IDAuNzUpCmBgYAoKYGBge3IgZWNobyA9IEZBTFNFfQojIE51bWJlciBvZiBzYW1wbGVzIHBlciBSZWdpb24Kc2VsZWN0KHZpc2l0cy4xLCBWaXNpdElELCBSZWdpb24pICU+JQogIGNvdW50KFJlZ2lvbikgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBnZ3Bsb3QoLiwgYWVzKHggPSBSZWdpb24sIHkgPSBuLCBmaWxsID0gUmVnaW9uKSkgKwogIGdlb21fY29sKCkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwgdmp1c3QgPSAtMC41KSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIpICsKICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwgdGl0bGUgPSAiTm8uIHNhbXBsZXMgcGVyIFJlZ2lvbiIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKTGlrZSB3ZSBzYXcgYmVmb3JlLCB0aGUgbWFqb3JpdHkgb2Ygb3VyIHNhbXBsZXMgYXJlIGxvY2F0ZWQgaW4gdGhlIEd1bGYgb2YgQWxhc2thIChHT0EpLCBuYW1lbHkgU291dGhlYXN0IChTRUFrKSBhbmQgU291dGhjZW50cmFsIChTQ0FLKS4gSWYgd2Ugd2VyZSB0byBsb29rIGF0IGRpZmZlcmVuY2VzIGluIGNhdGFjaCBpbiB0aGUgR09BLCBpdCdkIGJlIGNvb2wgaWYgd2UgY291bGQgaW5jbHVkZSB0aGUgQWxldXRpYW4gc2FtcGxlcyB0b28uIE9idmlvdXNseSwgd2UnbGwgd2FudCB0byBhZGRyZXNzIHRob3NlIGZldyBpbnN0YW5jZXMgZnJvbSBBZ2hpeXVrLCBTaHVtYWdpbiwgYW5kIFl1bmFza2EsIGFuZCBpZGVhbGx5IHdlIGFnZ3JlZ2F0ZSB0aGVtIGludG8gb25lIG9yIHR3byBncm91cHMuIFdlIGFsc28gc2VlIHJlbGF0aXZlbHkgc21hbGwgc2FtcGxlIHNpemVzIGZyb20gQnJpc3RvbCBCYXkgYW5kIGZyb20gRWFzdCBCZWF1Zm9ydCwgd2hpY2ggbWF5IG9yIG1heSBub3QgYmUgcHJvaGliaXRpdmUgaW4gY29uZHVjdGluZyBtZWFuaW5nZnVsIHRlc3RzLiBPbmUgb3RoZXIgY29uc2lkZXJhdGlvbiBpcyB0aGUgY291cGxlIG9mIHNhbXBsZXMgYWxvbmcgdGhlIEJlcmluZyBTdHJhaXQgY29hc3Qgd2hpY2ggYXJlIGx1bXBlZCB0b2dldGhlciB3aXRoIGEgbGFyZ2VyIGNvbmNlbnRyYXRpb24gb2Ygc2FtcGxlcyBmcm9tIFNvdXRoIENodWtjaGkuCgpTb21lIG9mIG91ciBmaXJzdCBhbmFseXNlcyBzaG91bGQgc2VlIGlmIHRoZSBtb3JlIGlzb2xhdGVkIHNhbXBsZXMgYXJlIGRpZmZlcmVudCBmcm9tIHRoZSBvdGhlciBzYW1wbGVzLiBJZiBub3QsIHRoZW4gd2UgY2FuIGFnZ3JlZ2F0ZS4gSWYgeWVzLCB0aGVuIHdlIHNob3VsZCByZXBvcnQgYW55IHNpZ25pZmljYW50IHRlc3RzLgoKIyMgVGVtcG9yYWwgZGlzdHJpYnV0aW9uCgpOZXh0IHdlJ2xsIHdhbnQgdG8gdGFrZSBhIGxvb2sgYXQgaG93IG91ciBzYW1wbGVzIGRpc3RyaWJ1dGUgdGhyb3VnaG91dCB2YXJpb3VzIHRpbWUgcGVyaW9kcy4gVGhpcyB3aWxsIGdpdmUgdXMgYSBnb29kIGlkZWEgb2YgaG93IHdlbGwgb3VyIHNhbXBsZXMgbWF5IG9yIG1heSBub3Qgb3ZlcmxhcC0gcGFydGljdWxhcmx5LCB3ZSdsbCB3YW50IHRvIHNlZSBvdmVybGFwcyBpbiB5ZWFycyBhbmQgbW9udGhzIGZvciBiZXR0ZXIgY29tcGFyaXNvbnMgb2YgdGhlIGNhdGNoIGRhdGEuCgpgYGB7cn0KIyBGaXJzdCBjcmVhdGUgYSBkZiBzcGVjaWZpY2FsbHkgY29udGFpbmluZyBhdCB0aW1lIHZhcmlhYmxlcwp0aW1lcyA9IHZpc2l0cy4xICU+JQogIHNlbGVjdChWaXNpdElELCBEYXRlKSAlPiUKICBtdXRhdGUoWWVhciA9IHllYXIoRGF0ZSksCiAgICAgICAgIE1vbnRoID0gbW9udGgoRGF0ZSwgbGFiZWwgPSBUUlVFKSwKICAgICAgICAgV2VlayA9IHdlZWsoRGF0ZSksCiAgICAgICAgIERheSA9IHlkYXkoRGF0ZSkpCgojIFllYXIKdGltZXMgJT4lCiAgY291bnQoWWVhcikgJT4lCiAgZ2dwbG90KC4sIGFlcyh4ID0gWWVhciwgeSA9IG4pKSArCiAgZ2VvbV9jb2woKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCB2anVzdCA9IC0wLjUsIGNvbG9yID0gImJsdWUiKSArCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwsIHRpdGxlID0gIk5vLiBzYW1wbGVzIHBlciBZZWFyIikKCiMgWWVhciB3aXRob3V0IDE5NzYKdGltZXMgJT4lCiAgZmlsdGVyKFllYXIgPiAxOTgwKSAlPiUKICBjb3VudChZZWFyKSAlPiUKICBnZ3Bsb3QoLiwgYWVzKHggPSBZZWFyLCB5ID0gbikpICsKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHZqdXN0ID0gLTAuNSwgY29sb3IgPSAiYmx1ZSIpICsKICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwgdGl0bGUgPSAiTm8uIHNhbXBsZXMgcGVyIFllYXIgd2l0aG91dCAxOTc2IikKCiMgTW9udGgKdGltZXMgJT4lCiAgY291bnQoTW9udGgpICU+JQogIGdncGxvdCguLCBhZXMoeCA9IE1vbnRoLCB5ID0gbikpICsKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHZqdXN0ID0gLTAuNSwgY29sb3IgPSAiYmx1ZSIpICsKICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwgdGl0bGUgPSAiTm8uIHNhbXBsZXMgcGVyIE1vbnRoIikKCiMgV2Vlawp0aW1lcyAlPiUKICBjb3VudChXZWVrKSAlPiUKICBnZ3Bsb3QoLiwgYWVzKHggPSBXZWVrLCB5ID0gbikpICsKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIGhqdXN0ID0gLTAuMTUsIGFuZ2xlID0gOTAsIGNvbG9yID0gImJsdWUiKSArCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwsIHRpdGxlID0gIk5vLiBzYW1wbGVzIHBlciBXZWVrIikKCiMgRGF5IG9mIFllYXIKdGltZXMgJT4lCiAgY291bnQoRGF5KSAlPiUKICBkaXN0aW5jdCgpICU+JQogIGdncGxvdCguLCBhZXMoeCA9IERheSwgeSA9IG4pKSArCiAgZ2VvbV9jb2woKSArCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwsIHRpdGxlID0gIk5vLiBzYW1wbGVzIHBlciBEYXkgb2YgWWVhciIpCmBgYAoKQnkgeWVhciwgd2Ugc2VlIGEgbGFyZ2UgdmFyaWFiaWxpdHkgaW4gbnVtYmVyIG9mIHNhbXBsZXMsIGFzIHdlbGwgYXMgYSBsb25lIDE5NzYgeWVhciB3aGljaCBJIHJlY29nbml6ZSB0byBiZSBCbGFja2J1cm4ncyBkYXRhc2V0IGZyb20gTG93ZXIgQ29vayBJbmxldC4gVGhhdCAxOTc2IGlzIGFuIGludGVyZXN0aW5nIGRhdGFzZXQgdGhhdCBjb3VsZCBiZSB1c2VmdWwgZm9yIGEgbG9vayBhdCBjYXRjaGVzIG92ZXIgdGltZSBpbiB0aGF0IHNwZWNpZmljIGFyZWEsIGJ1dCBpdCdsbCBuZWVkIHRvIGJlIGV4Y2x1ZGVkIGZyb20gYW55IG90aGVyIGNvbXBhcmlzb25zLiBUaGUgbG93ZXN0IG51bWJlciBvZiBzYW1wbGVzIG9jY3VyIGluIDIwMTAsIDIwMjAsIGFuZCAyMDIxLiBXZSBtYXkgd2FudCB0byBwYXkgY2xvc2UgYXR0ZW50aW9uIHRvIHRoZXNlIHllYXJzIGluIGNhc2UgdGhleSBzaG93IHVwIGFzIG91dGxpZXJzLiBJdCBzZWVtcyB0aGF0IDE5OTYtMjAwMCBpcyBhIHBlcmlvZCBvZiBoZWF2eSBzYW1wbGluZywgZm9sbG93ZWQgYnkgdGhlIG1pZCAyMDEwcyBhbmQgc29tZXdoYXQgYWN0aXZlIHllYXIgaW4gMjAwNi4KCkJ5IG1vbnRoLCB3ZSBzZWUgYW4gb2J2aW91cyB1cHRpY2sgZHVyaW5nIHRoZSBzdW1tZXIgd2hpY2ggbWFrZXMgc2Vuc2UgZ2l2ZW4gd2ludGVyIGNvbmRpdGlvbnMgYWxvbmcgbW9zdCBvZiBBbGFza2EncyBjb2FzdCAobGlnaHQsIGljZSwgZXRjLikuIE1hcmNoIGFuZCBPY3RvYmVyIGFyZSBpbnRlcmVzdGluZyBtb250aHMgYmVjYXVzZSBvZiB0aGUgcG90ZW50aWFsIGZvciBpbXBhY3RzIG9uIGZpc2hlcyBkdXJpbmcgeWVhcnMgd2l0aCB3YXJtZXIgc2hvdWxkZXIgc2Vhc29ucy4gTm92ZW1iZXIgdGhydSBGZWJydWFyeSB3aWxsIGxpa2VseSBiZSByZW1vdmVkIGZvciBvdXIgcHVycG9zZXMuIE91ciBrZXkgbW9udGhzIGxvb2sgdG8gYmUgSnVuZSwgSnVseSBhbmQgQXVndXN0LCB3aXRoIHBvc3NpYmxlIGluY2x1c2lvbiBvZiBBcHJpbCwgTWF5LCBhbmQgU2VwdGVtYmVyLgoKSXQncyBpbnRlcmVzdGluZyBpZiB3ZSBsb29rIGF0IHRoZSBieS13ZWVrIGFuZCBieS1kYXkgZ3JhcGhzLCB3ZSBzZWUgYSBkaXAgaW4gc2FtcGxpbmcgYXJvdW5kIG1pZC1KdW5lL2Vhcmx5LUp1bHkuIE5vdCBzdXJlIHdoeSB0aGlzIGlzLSBtYXliZSByZWxhdGVkIHRvIG1vcmUgdGFyZ2V0aW5nIG9mIGp1dmVuaWxlIHNhbG1vbmlkcyBpbiBlYXJseSBKdW5lLCBvciBtYXliZSBzbyByZWR1Y2VkIGVmZm9ydCBhcm91bmQgdGhlIDR0aCBvZiBKdWx5IGhvbGlkYXkuCgojIyBZZWFyICYgbW9udGggYnkgcmVnaW9uCgpMZXQncyBub3cgc2VlIGhvdyBvdXIgc2FtcGxlcyBvdmVybGFwIGJ5IFJlZ2lvbiBhbmQgWWVhciwgYW5kIGJ5IFJlZ2lvbiBhbmQgTW9udGguIEZvciB0aGVzZSBwdXJwb3NlcywgbGV0J3MgY29tYmluZSB0aGUgQWxldXRpYW5zIGludG8gb25lIGdyb3VwIGZvciBub3csIGFuZCByZW1vdmUgdGhlIDE5NzYgZGF0YS4KCmBgYHtyfQojIFNhbXBsZXMgYnkgWWVhciBhbmQgUmVnaW9uLApsZWZ0X2pvaW4oZmlsdGVyKHRpbWVzLCBZZWFyID4gMTk4MCksCiAgICAgICAgICBzZWxlY3QodmlzaXRzLjEsIFZpc2l0SUQsIFJlZ2lvbiksIGJ5ID0gIlZpc2l0SUQiKSAlPiUKICBtdXRhdGUoUmVnaW9uID0gY2FzZV93aGVuKHN0cl9kZXRlY3QoUmVnaW9uLCAiQWxldXRpYW5zIikgfiAiQWxldXRpYW5zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICFzdHJfZGV0ZWN0KFJlZ2lvbiwgIkFsZXV0aWFucyIpIH4gUmVnaW9uKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gRGF0ZSwgeSA9IFJlZ2lvbiwgY29sb3IgPSBSZWdpb24pKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21faml0dGVyKHNpemUgPSAwLjUsIGFscGhhID0gMC43NSkgKwogIHN0YXRfc3VtbWFyeShnZW9tID0gInRleHQiLCB2anVzdCA9IC0xLjksIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgZnVuLmRhdGEgPSBmdW5jdGlvbih4KSB7CiAgICAgICAgICAgICAgICAgcmV0dXJuKGMoeSA9IG1lZGlhbih4KSwgbGFiZWwgPSBsZW5ndGgoeCkpKQogICAgICAgICAgICAgICB9KSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU3BlY3RyYWwiKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiV5IiwKICAgICAgICAgICAgICAgZGF0ZV9icmVha3MgPSAiMiB5ZWFycyIpICsKICBsYWJzKHggPSAiWWVhciIsIHkgPSAiUmVnaW9uIiwKICAgICAgIHRpdGxlID0gIlNhbXBsZXMgYnkgWWVhciBhbmQgUmVnaW9uIiwKICAgICAgIHN1YnRpdGxlID0gIk5vLiBzYW1wbGVzIGNlbnRlcmVkIG92ZXIgbWVkaWFuIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKIyBTYW1wbGVzIGJ5IE1vbnRoIGFuZCBSZWdpb24sCmxlZnRfam9pbihmaWx0ZXIodGltZXMsIFllYXIgPiAxOTgwKSwKICAgICAgICAgIHNlbGVjdCh2aXNpdHMuMSwgVmlzaXRJRCwgUmVnaW9uKSwgYnkgPSAiVmlzaXRJRCIpICU+JQogIG11dGF0ZShSZWdpb24gPSBjYXNlX3doZW4oc3RyX2RldGVjdChSZWdpb24sICJBbGV1dGlhbnMiKSB+ICJBbGV1dGlhbnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIXN0cl9kZXRlY3QoUmVnaW9uLCAiQWxldXRpYW5zIikgfiBSZWdpb24pKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBNb250aCwgeSA9IFJlZ2lvbiwgY29sb3IgPSBSZWdpb24pKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21faml0dGVyKHNpemUgPSAwLjUsIGFscGhhID0gMC43NSkgKwogIHN0YXRfc3VtbWFyeShnZW9tID0gInRleHQiLCB2anVzdCA9IC0xLjksIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgZnVuLmRhdGEgPSBmdW5jdGlvbih4KSB7CiAgICAgICAgICAgICAgICAgcmV0dXJuKGMoeSA9IG1lZGlhbih4KSwgbGFiZWwgPSBsZW5ndGgoeCkpKQogICAgICAgICAgICAgICB9KSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIpICsKICBsYWJzKHggPSAiTW9udGgiLCB5ID0gIlJlZ2lvbiIsCiAgICAgICB0aXRsZSA9ICJTYW1wbGVzIGJ5IE1vbnRoIGFuZCBSZWdpb24iLAogICAgICAgc3VidGl0bGUgPSAiRXhjbHVkaW5nIDE5NzY7IG5vLiBzYW1wbGVzIGxhYmVsbGVkIGJ5IG1vbnRoIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCkludGVyZXN0aW5nIHRoYXQgZWFjaCByZWdpb24ncyBzYW1wbGVzIGNlbnRlciBvbiBhIGRpZmZlcmVudCB5ZWFyLiBBdCBhIGdsYW5jZSwgSSBzZWUgdGhlIG1vc3Qgb3ZlcmxhcCBpbiAyMDA2IHdoZXJlIHRoZSBBbGV1dGlhbnMgYW5kIGJvdGggR09BIHJlZ2lvbnMgbG9vayB0byBoYXZlIHNpbWlsYXIgc2FtcGxlIGRlbnNpdGllcywgcGx1cyB0aGVyZSBpcyBhIHNtYXR0ZXJpbmcgb2YgQ2h1a2NoaS9CZWF1Zm9ydCBzYW1wbGluZyB0b28uIEluIDIwMDksIHRoZSBCcmlzdG9sIEJheSBzYW1wbGVzIG1heSBiZSBjb21wYXJlZCB3aXRoIGJvdGggR29BIHJlZ2lvbnMgYW5kIHRoZSBDaHVrY2hpL0JlYXVmb3J0LCBhbHRob3VnaCB0aGUgc2FtcGxlcyBsb29rIG1vcmUgc3BhcnNlIGFjcm9zcyB0aGUgcmVnaW9ucy4gQW5kIGluIDIwMTMsIHRoZSBDaHVrY2hpL0JlYXVmb3J0IGhhcyBnb29kIG92ZXJsYXAgd2l0aCBib3RoIEdPQSByZWdpb25zIGFnYWluLiBJIHNlZSBuaWNlIHBlcmlvZHMgb2YgY29tcGFyaXNvbiBiZXR3ZWVuIFNFQUsgYW5kIFNDQUssIGJ1dCB0aGVyZSBpcyBhbHNvIGEgY29uY2VybmluZyBkaWZmZXJlbmNlIGluIHllYXJseSBkaXN0cmlidXRpb24gb2Ygc2FtcGxlcyBiZXR3ZWVuIHRoZSB0d28gcmVnaW9ucy4gRGVwZW5kaW5nIG9uIGhvdyBpbXBvcnRhbnQgeWVhciBlZmZlY3RzIGFwcGVhci0gd2UgbWF5IG5lZWQgdG8gdHJpbSB0aGUgZGF0YSBmb3IgYmV0dGVyIGNvbXBhcmlzb25zLgoKQnkgbW9udGgsIHdlIHNlZSB0aGF0IEF1Z3VzdCBjb250YWlucyBzYW1wbGVzIGZyb20gYWxsIHJlZ2lvbnMuIEp1bmUgaXMgdGhlIGNlbnRlciBmb3IgU0VBSyBhbmQgdGhlIEFsZXV0aWFucywgSnVseSBmb3IgU0NBSywgYW5kIEF1Z3VzdCBmb3IgQ2h1a2NoaS9CZWF1Zm9ydC4gQmVzdCBjb21wYXJpc29ucyBmcm9tIHRoaXMgbW9udGhseSB2aWV3IG1heSBiZSBhbiBBdWd1c3QgKG9yIGx1bXBlZCBKdWx5ICsgQXVndXN0KSBjb21wYXJpc29uIG9mIGFsbCBSZWdpb25zLiBBbHNvLCBhIEp1bmUgKG9yIGx1bXBlZCBKdW5lIHRocnUgQXVndXN0KSBjb21wYXJpc29uIG9mIEdPQSBhbmQgdGhlIEFsZXV0aWFucyB3b3VsZCBiZSBnb29kLiBBbmQsIHdlIHNob3VsZCBiZSBhYmxlIHRvIG5pY2VseSBjb21wYXJlIFNFQUsgYW5kIFNDQUsgZnJvbSBNYXkgdG8gU2VwdGVtYmVyLCBwb3RlbnRpYWxseSBpbmNsdWRpbmcgQXByaWwuCgpGb3Igbm93LCB3ZSdsbCBob2xkIG9mZiBvbiBleGNsdWRpbmcgYW55IG9mIHRoZSBkYXRhLiBJdCdsbCBiZSBiZXR0ZXIgdG8gcmV2aXNpdCB0aGVzZSBjb25zaWRlcmF0aW9ucyBhZnRlciBkZWNpZGluZyB3aGljaCByZXNlYXJjaCBxdWVzdGlvbnMgdG8gdGFja2xlLCBzbyBzdWJzZXRzIG9mIHRoZSBkYXRhIGNhbiBiZSBtYWRlIHNwZWNpZmljIHRvIGVhY2ggb25lLgoKIyMgTWVzaCBTaXplIGFuZCBSZXBsaWNhdGVzCgpMZXQncyBtYWtlIHNpbWlsYXIgdmlzdWFscyBhcyBiZWZvcmUsIGJ1dCBub3cgZm9jdXMgb24gTWVzaCBTaXplIGFuZCBSZXBsaWNhdGVzIGluIHNwYWNlIGFuZCB0aW1lLiBGaXJzdCwgd2UgY2FuIHJlLW1hcCB0aGUgc2FtcGxlcyB0byBjb2xvciBieSBNZXNoIFNpemUgYW5kIHNpemUgb2YgcG9pbnRzIHJlbGF0aXZlIFJlcGxpY2F0ZXMgKGxhcmdlIGRvdHMgPSBtb3JlIHJlcGxpY2F0ZXMpLgoKYGBge3J9CiMgUGFsZXR0ZSBmdW5jdGlvbiB0byBjb2xvciBtYXJrZXJzCnBhbGV0dGUubWVzaCA9IGNvbG9yRmFjdG9yKHBhbGV0dGUgPSBicmV3ZXIucGFsKG4gPSB2aXNpdHMuMSRNZXNoU2l6ZSAlPiUgbl9kaXN0aW5jdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gJ1NwZWN0cmFsJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbiA9IGZhY3Rvcih2aXNpdHMuMSRNZXNoU2l6ZSkpCiMgTWFwCmxlYWZsZXQodmlzaXRzLjEpICU+JSAKICBhZGRUaWxlcygpICU+JQogIGFkZENpcmNsZU1hcmtlcnMobG5nID0gfkxvbiwgbGF0ID0gfkxhdCwKICAgICAgICAgICAgICAgICAgIHJhZGl1cyA9IH4oc3FydChSZXBsaWNhdGVzKjE1KSksCiAgICAgICAgICAgICAgICAgICBjb2xvciA9IH5wYWxldHRlLm1lc2goTWVzaFNpemUpLAogICAgICAgICAgICAgICAgICAgZmlsbENvbG9yID0gfnBhbGV0dGUubWVzaChNZXNoU2l6ZSksCiAgICAgICAgICAgICAgICAgICBwb3B1cCA9IH5WaXNpdElELAogICAgICAgICAgICAgICAgICAgc3Ryb2tlID0gRkFMU0UpICU+JQogIGFkZExlZ2VuZChwb3NpdGlvbiA9ICJib3R0b21yaWdodCIsCiAgICAgICAgICAgIHBhbCA9IHBhbGV0dGUubWVzaCwgdmFsdWVzID0gfk1lc2hTaXplLAogICAgICAgICAgICB0aXRsZSA9ICJNZXNoIFNpemUgKG1tKSIsCiAgICAgICAgICAgIG9wYWNpdHkgPSAwLjc1KQpgYGAKCkkgaGF2ZSBhbiBpc3N1ZSBkaXNjZXJuaW5nIGFtb25nIHRoZSBzZXZlbiBkaWZmZXJlbnQgc2l6ZXMgc2luY2UgdGhvc2Ugd2FybWVyIGNvbG9ycyBkbyBub3QgZGl2ZXJnZSB3ZWxsLiBBbHRob3VnaCB0aGVyZSBhcmUgc29tZSBwYXR0ZXJucyB0byBtYWtlIG5vdGUgb2Y6IHRoZSBsYXJnZXN0IG1lc2ggc2l6ZSBvZiAxMi43IG9ubHkgb2NjdXJzIGluIGEgc21hbGwgYXJlYSBvZiBTRUFLLCB0aGUgMTAgbW0gc2FtcGxlcyBzaW1pbGFybHkgb25seSBvY2N1ciB3aXRoIHRoZSAxMi43IG1tIHNhbXBsZXMgKGxpa2VseSB0aGUgW0x1bmRzdHJvbSBldCBhbC4gMjAyMl0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwMDcvczEyMjM3LTAyMi0wMTA1Ny14KSBnZWFyIGNvbXBhcmlzb24pLCBhbmQgdGhlIHNtYWxsZXN0IHNpemUgYXQgMyBtbSBvbmx5IG9jY3VycyBpbiBDb29rIElubGV0LiBJIGRvbid0IHNlZSBhbnkgb2J2aW91cyBzcGF0aWFsIHBhdHRlcm5zIGluIFJlcGxpY2F0ZXMsIGFsdGhvdWdoIHRoaXMgbWF5IG5vdCBiZSB0aGUgYmVzdCB2aWV3IG9mIGl0LgoKTGV0J3Mgc2VlIHRoZSBmcmVxdWVuY3kgb2Ygc2FtcGxlcyBmb3IgYm90aCB2YXJpYWJsZXM6CgpgYGB7cn0KIyBUYWJsZSB2aWV3CnRhYmxlKHZpc2l0cy4xJE1lc2hTaXplKQp0YWJsZSh2aXNpdHMuMSRSZXBsaWNhdGVzKQpgYGAKVGhlcmUgYXJlIG1vcmUgMTIuNyBtbSBzYW1wbGVzIHRoYW4gSSB3b3VsZCBoYXZlIGd1ZXNzZWQgd2hpY2ggaXMgYSBzaGFtZSBiZWNhdXNlIGlmIHRoZXkgYXJlIGNvbXBsZXRlbHkgZGlmZmVyZW50IHRoZW4gd2UgbG9zZSBhIGxvdCBvZiBzYW1wbGVzLiBJIGFtIHdvbmRlcmluZyBpZiBzaXplcyBhcmUgYWNjdXJhdGUtIEkgd291bGQgdGhpbmsgdGhhdCAzIG1tIGFuZCAzLjIgbW0gYXJlIGVmZmVjdGl2ZWx5IHNpbWlsYXIgaW4gcHJhY3RpY2UuIEkgYW0gYWxzbyB3b25kZXJpbmcgaWYgc29tZSBwcm9qZWN0cyByZXBvcnQsIHNheSAzIG1tIGluc3RlYWQgb2YgMy4yIG1tLCBiZWNhdXNlIG9mIHJvdW5kaW5nLiBJIHdvdWxkIGFzc3VtZSB0aGF0IHRoZSBuZXRzIHVzZWQgd2VyZSBtYW51ZmFjdHVyZWQgaW4gdGhlIFVTLCB3aGljaCB3b3VsZCBtZWFuIHRoYXQgc3BlY2lmaWNhdGlvbnMgYXJlIGdpdmVuIGluIHN0YW5kYXJkIG5vdCBtZXRyaWMuIExldCdzIGRvIGEgcXVpY2sgY2hlY2sgb24gaG93IHR5cGljYWwgbWVzaCBzaXplcyBjb252ZXJ0IGZyb20gaW5jaGVzIHRvIG1pbGxpbWV0ZXJzLgoKYGBge3J9CiMgRnVuY3Rpb24gYmFzZWQgb24gaW5jaCB0byBtaWxsaW1ldGVyIGNvbnZlcnNpb24KaW5fdG9fbW0gPSBmdW5jdGlvbiAoeCkgewogIHJldHVybih5ID0gMjUuNCAqIHgpCn0KCiMgVHlwaWNhbCBtZXNoIHNpemVzIGluIGluY2hlcwpzaXplcyA9IGMoKDEvOCksICgxLzQpLCAoMy84KSwgKDEvMiksICg1LzgpLCAoMy80KSkKCiMgQ29udmVydCB0byBtaWxsaW1ldGVycwppbl90b19tbShzaXplcykKYGBgCgpUaGVyZSBpcyBvYnZpb3VzbHkgc29tZSBmdW5ueSByb3VuZGluZyBoYXBwZW5pbmcgaW4gdGhlIGRhdGEuIEkgZG8gbm90IHNlZSBhbiBpc3N1ZSBieSBsdW1waW5nIG1lc2ggc2l6ZXMgdGhhdCBhcmUgd2l0aGluIG9uZSBtaWxsaW1ldGVyLiBFdmVuIGlmIHRoZSBuZXRzIHdlcmUgYWN0dWFsbHkgZGlmZmVyZW50IGJ5IGZyYWN0aW9ucyBvZiBhIG1pbGxpbWV0ZXIsIEkgZG9uJ3QgdGhpbmsgaXQgd291bGQgYWZmZWN0IHRoZSBzZWxlY3Rpdml0eSBvZiBmaXNoZXMgYWxsIHRoYXQgbXVjaC0gZXNwZWNpYWxseSBjb25zaWRlcmluZyB0aGF0IG1vc3Qgb2YgdGhlc2UgcmVzZWFyY2hlcnMgd2VyZSBjYXB0dXJpbmcgZmlzaCB0byBiZSBtZWFzdXJlZCB0byB0aGUgbmVhcmVzdCBtaWxsaW1ldGVyLgoKTGV0J3Mgc2VlIHRoYXQgbWFwIGFnYWluIHdpdGggdGhpcyBpbiBtaW5kOgoKYGBge3J9CiMgUGFsZXR0ZSBmdW5jdGlvbiBmb3IgYmlubmVkIHNpemVzCnBhbGV0dGUubWVzaC5iaW4gPSBjb2xvckJpbihwYWxldHRlID0gYnJld2VyLnBhbChuID0gNCwgbmFtZSA9ICdTcGVjdHJhbCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tYWluID0gdmlzaXRzLjEkTWVzaFNpemUgJT4lIHVuaXF1ZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmlucyA9ICBjKDAsIDQsIDcsIDExLCAxMykpCiMgTWFwCmxlYWZsZXQodmlzaXRzLjEpICU+JSAKICBhZGRUaWxlcygpICU+JQogIGFkZENpcmNsZU1hcmtlcnMobG5nID0gfkxvbiwgbGF0ID0gfkxhdCwKICAgICAgICAgICAgICAgICAgIHJhZGl1cyA9IH4oc3FydChSZXBsaWNhdGVzKjE1KSksCiAgICAgICAgICAgICAgICAgICBjb2xvciA9IH5wYWxldHRlLm1lc2guYmluKE1lc2hTaXplKSwKICAgICAgICAgICAgICAgICAgIGZpbGxDb2xvciA9IH5wYWxldHRlLm1lc2guYmluKE1lc2hTaXplKSwKICAgICAgICAgICAgICAgICAgIHBvcHVwID0gflZpc2l0SUQsCiAgICAgICAgICAgICAgICAgICBzdHJva2UgPSBGQUxTRSkgJT4lCiAgYWRkTGVnZW5kKHBvc2l0aW9uID0gImJvdHRvbXJpZ2h0IiwKICAgICAgICAgICAgY29sb3JzID0gYyhwYWxldHRlLm1lc2guYmluKDMpLAogICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUubWVzaC5iaW4oNiksCiAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZS5tZXNoLmJpbig5KSwKICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlLm1lc2guYmluKDEyKSksCiAgICAgICAgICAgIHZhbHVlcyA9IH5NZXNoU2l6ZSwKICAgICAgICAgICAgdGl0bGUgPSAiTWVzaCBTaXplIChtbSkiLAogICAgICAgICAgICBvcGFjaXR5ID0gMC43NSwKICAgICAgICAgICAgbGFiZWxzID0gYygiMyBvciAzLjIiLCAiNiBvciA2LjQiLCAiOS41IG9yIDEwIiwgIjEyLjciKSkKYGBgCgpNdWNoIGVhc2llciB0byByZWFkISBJIHNlZSBzb21lIGNvbmNlcm5pbmcgcGF0dGVybnMgd2UnbGwgd2FudCB0byBpbnZlc3RpZ2F0ZSBmdXJ0aGVyIGFzIHdlIGdvLiBUaGUgbWFqb3JpdHkgb2Ygc2FtcGxlcyBhcHBlYXIgdG8gYmUgdXNpbmcgdGhlIDMuMiBtbSBzaXplLCBpbmNsdWRpbmcgYm90aCBBcmN0aWMgZ3JvdXBzIHRoYXQgc2VlbSB0byB1c2UgaXQgZXhjbHVzaXZlbHkuIFRoZXJlIGlzIGEgbGFyZ2UgZGVuc2l0eSBvZiA2LjQgbW0gc2FtcGxlcyBpbiBOb3J0aGVybiBTRUFLIGFuZCB0aHJvdWdob3V0IHRoZSBBbGV1dGlhbnMuIFRoZSBzYW1lIGlzc3VlcyBhcmUgdmlzaWJsZSBjb25jZXJuaW5nIHRoZSB0d28gbGFyZ2VyIG1lc2ggc2l6ZXMuIFdlIHNob3VsZCBkbyBhIGNvbXBhcmlzb24gb2YgMy4yIG1tIGFuZCA2LjQgbW0gdG8gc2VlIGlmIHRoZXJlIGFyZSBhbnkgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgaW4gY2F0Y2guCgpXaXRoIHRoZSBzaW1wbGVyIGNvbG9yIHNjaGVtZSwgSSBhbSBhbHNvIG5vdGljaW5nIHRoZSBkaWZmZXJlbmNlIGluIFJlcGxpY2F0ZXMgYSBsaXR0bGUgZWFzaWVyLiBKdXN0IGxvb2tpbmcgYXQgR09BIGFuZCBBbGV1dGlhbiBzYW1wbGVzLCBJIHNlZSB0aGF0IG1hbnkgb2YgdGhlIDYuNCBtbSBzYW1wbGVzIGFyZSBhbHNvIGxvdy1SZXBsaWNhdGUgc2FtcGxlcy4gQWx0aG91Z2gsIG1hbnkgb2Ygb3VyIHNhbXBsZXMgb25seSBjb250YWluIG9uZSByZXBsaWNhdGUgc28gdGhpcyBtYXkganVzdCBiZSBzb21ldGhpbmcgSSdtIHNlZWluZyBhbmQgbm90IGFjdHVhbGx5IGEgY29uY2Vybi4KCkxldCdzIHRha2UgYSBsb29rIGF0IGhvdyB0aGVzZSB2YXJpYWJsZXMgaW4gZ3JhcGhpY2FsIGZvcm1hdC4gSSdsbCBnbyBhaGVhZCBhbmQgYWdncmVnYXRlIHNpbWlsYXIgbWVzaCBzaXplcyBhbmQgcmUtY2xhc3NpZnkgdGhlIGJvdGggdmFyaWFibGVzIGFzIGZhY3RvcnMsIGFuZCBhZGQgaW4gdmFyaWFibGVzIGZvciB5ZWFyIGFuZCBtb250aC4KCmBgYHtyfQp2aXNpdHMuMiA9IG11dGF0ZSh2aXNpdHMuMSwKICAgICAgICAgICAgICAgICAgUmVwbGljYXRlcyA9IGFzX2ZhY3RvcihSZXBsaWNhdGVzKSwKICAgICAgICAgICAgICAgICAgIyBDb21iaW5lIHNpbWlsYXIgbWVzaCBzaXplcyB0byB0aGUgdGVudGggZGVjaW1hbAogICAgICAgICAgICAgICAgICBNZXNoU2l6ZSA9IGNhc2Vfd2hlbihNZXNoU2l6ZSA8IDQgfiAzLjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc2hTaXplID4gNCAmIE1lc2hTaXplIDwgNyB+IDYuNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzaFNpemUgPiA3ICYgTWVzaFNpemUgPCAxMSB+IDkuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzaFNpemUgPT0gMTIuNyB+IDEyLjcpICU+JQogICAgICAgICAgICAgICAgICAgIGFzLmZhY3RvcigpKSAlPiUKICAjIEFkZCB0ZW1wb3JhbCB2YXJpYWJsZXMKICBsZWZ0X2pvaW4oc2VsZWN0KHRpbWVzLCBWaXNpdElELCBZZWFyLCBNb250aCksIGJ5ID0gIlZpc2l0SUQiKQpgYGAKCmBgYHtyfQojIFNhbXBsZXMgYnkgTWVzaFNpemUgYW5kIFllYXIsCmZpbHRlcih2aXNpdHMuMiwgWWVhciA+IDE5ODkpICU+JQogIGdncGxvdChhZXMoeCA9IERhdGUsIHkgPSBNZXNoU2l6ZSwgY29sb3IgPSBNZXNoU2l6ZSkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9qaXR0ZXIoc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjc1KSArCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAidGV4dCIsIHZqdXN0ID0gLTMsIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgZnVuLmRhdGEgPSBmdW5jdGlvbih4KSB7CiAgICAgICAgICAgICAgICAgcmV0dXJuKGMoeSA9IG1lZGlhbih4KSwgbGFiZWwgPSBsZW5ndGgoeCkpKQogICAgICAgICAgICAgICB9KSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU3BlY3RyYWwiKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiV5IiwKICAgICAgICAgICAgICAgZGF0ZV9icmVha3MgPSAiMiB5ZWFycyIpICsKICBsYWJzKHggPSAiWWVhciIsIHkgPSAiTWVzaCBTaXplIChtbSkiLAogICAgICAgdGl0bGUgPSAiU2FtcGxlcyBieSBZZWFyIGFuZCBNZXNoIFNpemUiLAogICAgICAgc3VidGl0bGUgPSAiRXhjbHVkaW5nIDE5NzY7IG5vLiBzYW1wbGVzIGNlbnRlcmVkIG92ZXIgbWVkaWFuIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKIyBTYW1wbGVzIGJ5IE1vbnRoIGFuZCBNZXNoU2l6ZSwKZmlsdGVyKHZpc2l0cy4yLCBZZWFyID4gMTk4OSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gTW9udGgsIHkgPSBNZXNoU2l6ZSwgY29sb3IgPSBNZXNoU2l6ZSkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9qaXR0ZXIoc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjc1KSArCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAidGV4dCIsIHZqdXN0ID0gLTMsIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgZnVuLmRhdGEgPSBmdW5jdGlvbih4KSB7CiAgICAgICAgICAgICAgICAgcmV0dXJuKGMoeSA9IG1lZGlhbih4KSwgbGFiZWwgPSBsZW5ndGgoeCkpKQogICAgICAgICAgICAgICB9KSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIpICsKICBsYWJzKHggPSAiTW9udGgiLCB5ID0gIk1lc2ggU2l6ZSAobW0pIiwKICAgICAgIHRpdGxlID0gIlNhbXBsZXMgYnkgTW9udGggYW5kIE1lc2ggU2l6ZSIsCiAgICAgICBzdWJ0aXRsZSA9ICJFeGNsdWRpbmcgMTk3Njsgbm8uIHNhbXBsZXMgbGFiZWxsZWQgYnkgbW9udGgiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgojIFNhbXBsZXMgYnkgUmVwbGljYXRlcyBhbmQgWWVhciwKZmlsdGVyKHZpc2l0cy4yLCBZZWFyID4gMTk4OSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gRGF0ZSwgeSA9IFJlcGxpY2F0ZXMsIGNvbG9yID0gUmVwbGljYXRlcykpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9qaXR0ZXIoc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjc1KSArCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAidGV4dCIsIHZqdXN0ID0gLTEsIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgZnVuLmRhdGEgPSBmdW5jdGlvbih4KSB7CiAgICAgICAgICAgICAgICAgcmV0dXJuKGMoeSA9IG1lZGlhbih4KSwgbGFiZWwgPSBsZW5ndGgoeCkpKQogICAgICAgICAgICAgICB9KSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU3BlY3RyYWwiKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiV5IiwKICAgICAgICAgICAgICAgZGF0ZV9icmVha3MgPSAiMiB5ZWFycyIpICsKICBsYWJzKHggPSAiWWVhciIsIHkgPSAiUmVwbGljYXRlcyIsCiAgICAgICB0aXRsZSA9ICJTYW1wbGVzIGJ5IFllYXIgYW5kIFJlcGxpY2F0ZXMiLAogICAgICAgc3VidGl0bGUgPSAiRXhjbHVkaW5nIDE5NzY7IG5vLiBzYW1wbGVzIGNlbnRlcmVkIG92ZXIgbWVkaWFuIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKIyBTYW1wbGVzIGJ5IFJlcGxpY2F0ZXMgYW5kIE1vbnRoLApmaWx0ZXIodmlzaXRzLjIsIFllYXIgPiAxOTg5KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBNb250aCwgeSA9IFJlcGxpY2F0ZXMsIGNvbG9yID0gUmVwbGljYXRlcykpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9qaXR0ZXIoc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjc1KSArCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAidGV4dCIsIHZqdXN0ID0gLTEsIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgZnVuLmRhdGEgPSBmdW5jdGlvbih4KSB7CiAgICAgICAgICAgICAgICAgcmV0dXJuKGMoeSA9IG1lZGlhbih4KSwgbGFiZWwgPSBsZW5ndGgoeCkpKQogICAgICAgICAgICAgICB9KSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIpICsKICBsYWJzKHggPSAiTW9udGgiLCB5ID0gIlJlcGxpY2F0ZXMiLAogICAgICAgdGl0bGUgPSAiU2FtcGxlcyBieSBNb250aCBhbmQgUmVwbGljYXRlcyIsCiAgICAgICBzdWJ0aXRsZSA9ICJFeGNsdWRpbmcgMTk3Njsgbm8uIHNhbXBsZXMgbGFiZWxsZWQgYnkgbW9udGgiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYAoK